/*******************************************************************************

ATTENTION, this is an altered version of the xhtml_gen library, specifically tailored to libwebconf's needs please refer to the original library

xhtml_gen: xhtml generation library.
Copyright (c) 2006  Mitchel Haas

This software is provided 'as-is', without any express or implied warranty. 
In no event will the author be held liable for any damages arising from 
the use of this software.

Permission is granted to anyone to use this software for any purpose, 
including commercial applications, and to alter it and redistribute it freely, 
subject to the following restrictions:

1.	The origin of this software must not be misrepresented; 
you must not claim that you wrote the original software. 
If you use this software in a product, an acknowledgment in the product 
documentation would be appreciated but is not required.

2.	Altered source versions must be plainly marked as such, 
and must not be misrepresented as being the original software.

3.	The above copyright notice and this permission notice may not be removed 
or altered from any source distribution.

For complete documentation on this library, see http://www.datasoftsolutions.net
Email questions, comments or suggestions to mhaas@datasoftsolutions.net
*******************************************************************************/
#pragma once
#include "xhtml_def.hpp"
#include <set>
#include <string>

namespace xhtml_gen 
{

class tag_trait_manager;

class tag_trait
{
private:
	tag_trait(	const xhtml_strict _tag_enum, 
				const std::string& _tag_name, 
				const nesting_type _box_type, 
				const nesting_type nested_type, 
				const std::set<attribute>& _allowed_attributes,
				const std::set<xhtml_strict>& _nested_tags,
				const std::set<xhtml_strict>& _nested_exceptions );

	~tag_trait();

public:
	friend bool operator < (const tag_trait& lhs, const tag_trait& rhs) { return lhs.tag_enum < rhs.tag_enum; }

	nesting_type get_nesting_type() const { return tag_nesting_type; }
	xhtml_strict get_tag_enumeration() const { return tag_enum; }
	std::string get_tag_name() const { return tag_name; }
	nesting_type get_nested_type() const { return allowed_nested_type; }
	const std::set<xhtml_strict>& get_nested_tags() const { return allowed_nested_tags; }
	const std::set<xhtml_strict>& get_nested_exceptions() const { return nested_exceptions; }
	bool check_attribute(const attribute attrib) const;
	bool check_style(const css_property _property) const;
	std::string get_attribute_name(const attribute _attribute) const;
	friend class tag_trait_manager;

private:
	void add_allowed_nested_tag(xhtml_strict _tag_enum) { allowed_nested_tags.insert(_tag_enum); }
	void remove_allowed_nested_tag(xhtml_strict _tag_enum) { allowed_nested_tags.erase(_tag_enum); }
	void add_nested_exception(xhtml_strict _tag_enum) { nested_exceptions.insert(_tag_enum); }
	void remove_nested_exception(xhtml_strict _tag_enum) { nested_exceptions.erase(_tag_enum); }
	void remove_attributes(const attribute* attribs, int count);

private:
	xhtml_strict tag_enum;
	std::string tag_name;
	nesting_type tag_nesting_type;
	nesting_type allowed_nested_type;
	std::set<xhtml_strict> allowed_nested_tags;
	std::set<xhtml_strict> nested_exceptions;
	std::set<attribute> attributes;
	std::set<css_property> properties;
};






}

